<template>
  <div class="prism-player" :id="playerId" :style="playStyle"></div>
</template>

<script>
  export default {
    name: "Aliplayer",
    props: {
      source: {
        type: String,
        default: ""
      },
      //媒体转码服务的媒体Id。
      vid: {
        type: String,
        default: ""
      },
      //播放权证
      playauth: {
        type: String,
        default: ""
      },
      //容器的大小
      height: {
        type: String,
        default: "320px"
      },
      //容器的大小
      width: {
        type: String,
        default: "100%"
      },
      //视频的高度大小
      videoWidth: {
        type: String,
        default: "100%"
      },
      //视频的宽度大小
      videoHeight: {
        type: String,
        default: "320px"
      },
      //播放器自动加载，目前仅h5可用
      preload: {
        type: Boolean,
        default: false
      },
      //播放器默认封面图片，请填写正确的图片url地址。需要autoplay为’false’时，才生效
      cover: {
        type: String,
        default: ""
      },
      //播放内容是否为直播，直播时会禁止用户拖动进度条。
      isLive: {
        type: Boolean,
        default: false
      },
      //播放器是否自动播放，在移动端autoplay属性会失效。
      autoplay: {
        type: Boolean,
        default: false
      },
      //播放器自动循环播放。
      rePlay: {
        type: Boolean,
        default: false
      },
      //指定使用H5播放器。
      useH5Prism: {
        type: Boolean,
        default: false
      },
      //指定使用Flash播放器。
      useFlashPrism: {
        type: Boolean,
        default: false
      },
      //H5是否内置播放，有的Android浏览器不起作用。
      playsinline: {
        type: Boolean,
        default: false
      },
      //显示播放时缓冲图标，默认true。
      showBuffer: {
        type: Boolean,
        default: true
      },
      //URL 皮肤图片，不建议随意修改该字段，如要修改，请参照皮肤定制。
      skinRes: {
        type: String,
        default: ""
      },

      skinLayout: {
        type: Array,
        default: function () {
          return []
        }
      },
      //默认为‘hover’。可选的值为：‘click’、‘hover’、‘always’。
      controlBarVisibility: {
        type: String,
        default: "hover"
      },
      //控制栏自动隐藏时间（ms）
      showBarTime: {
        type: String,
        default: ""
      },
      /***
       * JSON串用于定制性接口参数，目前支持：
       1.“fullTitle”：“测试页面”
       全屏时显示视频标题（仅flash支持）。
       2. “m3u8BufferLength”：“30”
       播放m3u8时加载缓存ts文件长度单位（秒）（仅flash支持）。
       3. “liveStartTime”：“2016/08/17 12:00:00”
       直播开始时间，用于提示直播未开始(仅flash支持)。
       4. “liveOverTime”：“2016/08/17 14:00:00”
       直播结束时间，用于提示直播结束（仅flash支持）。
       */
      extraInfo: {
        type: String,
        default: ""
      },

      /**
       *是否允许系统右键菜单显示，默认为false。
       */
      enableSystemMenu: {
        type: Boolean,
        default: false
      },

      /***
       *
       *指定播放地址格式，只有使用vid的播放方式时支持
       可选值为’mp4’、’m3u8’、’flv’、’mp3’，默认为空，仅H5支持。
       * */
      format: {
        type: String,
        default: "mp4"
      },
      /***
       *
       * 指定返回音频还是视频，只有使用vid的播放方式时支持。
       可选值为’video’和’audio’，默认为’video’
       ‘audio’主要是针对只包含音频的视频格式，比如音频的mp4，仅H5支持。
       * */
      mediaType: {
        type: String,
        default: "video"
      },
      /***
       * 指定排序方式，只有使用vid + plauth播放方式时支持。
       ‘desc’表示按倒序排序（即：从大到小排序）
       ‘asc’表示按正序排序（即：从小到大排序）
       默认值：‘asc’，仅H5支持。
       * */
      qualitySort: {
        type: String,
        default: "asc"
      },
      /***
       * 显示视频清晰度，多个用逗号分隔，比如：’FD,LD’，此值是vid对应流清晰度的一个子集，
       取值范围：FD（流畅）LD（标清）SD（高清）HD（超清）OD（原画）2K（2K）4K（4K），仅H5支持。
       * */
      definition: {
        type: String,
        default: ""
      },
      /**
       * 默认视频清晰度，此值是vid对应流的一个清晰度，
       取值范围：FD（流畅）LD（标清）SD（高清）HD（超清）OD（原画）2K（2K）4K（4K），仅H5支持。
       * */
      defaultDefinition: {
        type: String,
        default: ""
      },
      /**
       * 声明启用同层H5播放器，启用时设置的值为‘h5’
       * */
      x5_type: {
        type: String,
        default: "h5"
      },
      /**
       * 声明视频播放时是否进入到TBS的全屏模式，默认为false。
       当需要把视频做为背景时，设置为true
       * */
      x5_fullscreen: {
        type: Boolean,
        default: false
      },
      /**
       * 声明视频播在界面上的位置，默认为“center”。
       可选值为：“top”，“center”
       * */
      x5_video_position: {
        type: String,
        default: "center"
      },
      /**
       * 声明 TBS 播放器支持的方向，可选值：
       landscape:横屏）
       portraint:竖屏
       landscape
       * */
      x5_orientation: {
        type: String,
        default: "portraint"
      },
      /**
       * 声明TBS全屏播放是否横屏，默认值为true。
       * */
      x5LandscapeAsFullScreen: {
        type: String,
        default: "true"
      },
      /**
       * 延迟播放时间，单位为秒。
       * */
      autoPlayDelay: {
        type: Number,
        default: 0
      },
      /**
       * 延迟播放提示文本
       * */
      autoPlayDelayDisplayText: {
        type: String,
        default: "正在转码，请稍后......"
      },
      /**
       * 国际化，默认为‘zh-cn’。
       如果未设置，则采用浏览器语言。
       可选值为‘zh-cn’、‘en-us’或其它值。
       * */
      language: {
        type: String,
        default: "zh-cn"
      },
      /**
       * 自定义国际化文本json结构，key的值需要和language属性值对应起来。
       例子：{jp:{Play:”Play”}}
       * */
      languageTexts: {
        type: Object,
        default: function () {
          return {}
        }
      },
      /**
       * flash启用截图功能
       * */
      snapshot: {
        type: Boolean,
        default: false
      },
      /**
       * H5设置截图水印。
       * */
      snapshotWatermark: {
        type: Object,
        default: function () {
          return {}
        }
      },
      /**
       * Safari浏览器可以启用Hls插件播放，Safari 11除外。
       * */
      useHlsPluginForSafari: {
        type: Boolean,
        default: false
      },
      /**
       * H5播放flv时，设置是否启用播放缓存，只在直播下起作用。
       * */
      enableStashBufferForFlv: {
        type: Boolean,
        default: false
      },
      /**
       * H5播放flv时，初始缓存大小，只在直播下起作用。
       * */
      stashInitialSizeForFlv: {
        type: Number,
        default: 10
      },
      /**
       * 缓冲多长时间后，提示用户切换低清晰度，默认：20秒。
       * */
      loadDataTimeout: {
        type: Number,
        default: 20
      },
      /**
       *最大缓冲超时时间，超过这个时间会有错误提示，默认：60秒。
       * */
      waitingTimeout: {
        type: Number,
        default: 60
      },
      /**
       * 直播开始时间，直播时移功能使用，格式为：“2018/01/04 12:00:00”。
       * */
      liveStartTime: {
        type: String,
        default: ""
      },
      /**
       * 直播结束时间，直播时移功能使用，格式为：“2018/01/04 12:00:00”。
       * */
      liveOverTime: {
        type: String,
        default: ""
      },
      /**
       * 直播可用时移查询地址，详情参见直播时移。
       * https://help.aliyun.com/document_detail/65129.html?spm=a2c4g.11186623.2.28.3603bf80LR74sS
       * */
      liveTimeShiftUrl: {
        type: String,
        default: ""
      },
      /**
       * flv直播和hls时移切换是，重新创建播放器方法，详情参见直播时移。
       * https://help.aliyun.com/document_detail/65129.html?spm=a2c4g.11186623.2.28.3603bf80LR74sS
       * */
      recreatePlayer: {
        type: Function,
        default: function () {
        }
      },
      /**
       *是否显示检测按钮，默认为true。
       * */
      diagnosisButtonVisible: {
        type: Boolean,
        default: true
      },
      /**
       * 禁用进度条的Seek，默认为false，仅Flash支持。
       * */
      disableSeek: {
        type: Boolean,
        default: false
      },
      /**
       * 加密类型，播放点播私有加密视频时，设置值为1，默认值为0。
       * */
      encryptType: {
        type: Number,
        default: 0
      },
      /**
       * 进度条打点内容数组，详情参见进度条打点。
       * [
       {offset:0,text:'阿里视频云端到云到端服务的重要一环'},
       {offset:10,text:'除了支持点播和直播的基础播放功能外'},
       {offset:20,text:'深度融合视频云业务'},
       {offset:30,text:'为用户提供简单、快速、安全、稳定的视频播放服务'},
       {offset:40,text:'安装播放器Demo进行体验'},
       {offset:50,text:'开发人员请点击SDK下载'}
       ]
       * https://yq.aliyun.com/articles/686043?spm=a2c4g.11186623.2.31.3603bf80LR74sS
       * */
      progressMarkers: {
        type: Array,
        default: function () {
          return []
        }
      },
      /**
       * 点播失败重试次数，默认3次
       * */
      vodRetry: {
        type: Number,
        default: 3
      },
      /**
       * 直播播放失败重试次数，默认5次
       * */
      liveRetry: {
        type: Number,
        default: 5
      },

      playStyle: {
        type: String,
        default: ""
      },
      aliplayerSdkPath: {
        // Aliplayer 代码的路径
        type: String,
        default: "//g.alicdn.com/de/prismplayer/2.8.2/aliplayer-min.js"
      },


    },
    data() {
      return {
        playerId: "aliplayer_" + Math.random().toString(36).substr(2),
        scriptTagStatus: 0,
        isReload: false,
        instance: null
      };
    },
    created() {
      if (window.Aliplayer !== undefined) {
        // 如果全局对象存在，说明编辑器代码已经初始化完成，直接加载编辑器
        this.scriptTagStatus = 2;
        this.initAliplayer();
      } else {
        // 如果全局对象不存在，说明编辑器代码还没有加载完成，需要加载编辑器代码
        this.insertScriptTag();
      }
    },
    mounted() {
      if (window.Aliplayer !== undefined) {
        // 如果全局对象存在，说明编辑器代码已经初始化完成，直接加载编辑器
        this.scriptTagStatus = 2;
        this.initAliplayer();
      } else {
        // 如果全局对象不存在，说明编辑器代码还没有加载完成，需要加载编辑器代码
        this.insertScriptTag();
      }
    },
    methods: {
      insertScriptTag() {
        const _this = this;
        let playerScriptTag = document.getElementById("playerScriptTag");
        // 如果这个tag不存在，则生成相关代码tag以加载代码
        if (playerScriptTag === null) {
          playerScriptTag = document.createElement("script");
          playerScriptTag.type = "text/javascript";
          playerScriptTag.src = this.aliplayerSdkPath;
          playerScriptTag.id = "playerScriptTag";
          let s = document.getElementsByTagName("head")[0];
          s.appendChild(playerScriptTag);
        }
        if (playerScriptTag.loaded) {
          _this.scriptTagStatus++;
        } else {
          playerScriptTag.addEventListener("load", () => {
            _this.scriptTagStatus++;
            playerScriptTag.loaded = true;
            _this.initAliplayer();
          });
        }
        _this.initAliplayer();
      },
      initAliplayer() {
        const _this = this;
        // scriptTagStatus 为 2 的时候，说明两个必需引入的 js 文件都已经被引入，且加载完成
        if (
          _this.scriptTagStatus === 2 &&
          (_this.instance === null || _this.reloadPlayer)
        ) {
          _this.instance && _this.instance.dispose();

          document.querySelector("#" + _this.playerId).innerHTML = "";

          // Vue 异步执行 DOM 更新，这样一来代码执行到这里的时候可能 template 里面的 script 标签还没真正创建
          // 所以，我们只能在 nextTick 里面初始化 Aliplayer
          _this.$nextTick(() => {
            _this.instance = window.Aliplayer({
              id: _this.playerId,
              source: _this.source,
              vid: _this.vid,
              playauth: _this.playauth,
              width: _this.width,
              height: _this.height,
              videoWidth: _this.videoWidth,
              videoHeight: _this.videoHeight,
              preload: _this.preload,
              cover: _this.cover,
              isLive: _this.isLive,
              autoplay: _this.autoplay,
              rePlay: _this.rePlay,
              useH5Prism: _this.useH5Prism,
              useFlashPrism: _this.useFlashPrism,
              playsinline: _this.playsinline,
              showBuffer: _this.showBuffer,
              skinRes: _this.skinRes,
              skinLayout: _this.skinLayout,
              controlBarVisibility: _this.controlBarVisibility,
              showBarTime: _this.showBarTime,
              extraInfo: _this.extraInfo,
              enableSystemMenu: _this.enableSystemMenu,
              format: _this.format,
              mediaType: _this.mediaType,
              qualitySort: _this.qualitySort,
              definition: _this.definition,
              defaultDefinition: _this.defaultDefinition,
              x5_type: _this.x5_type,
              x5_fullscreen: _this.x5_fullscreen,
              x5_video_position: _this.x5_video_position,
              x5_orientation: _this.x5_orientation,
              x5LandscapeAsFullScreen: _this.x5LandscapeAsFullScreen,
              autoPlayDelay: _this.autoPlayDelay,
              autoPlayDelayDisplayText: _this.autoPlayDelayDisplayText,
              language: _this.language,
              languageTexts: _this.languageTexts,
              snapshot: _this.snapshot,
              snapshotWatermark: _this.snapshotWatermark,
              useHlsPluginForSafari: _this.useHlsPluginForSafari,
              enableStashBufferForFlv: _this.enableStashBufferForFlv,
              stashInitialSizeForFlv: _this.stashInitialSizeForFlv,
              loadDataTimeout: _this.loadDataTimeout,
              waitingTimeout: _this.waitingTimeout,
              liveStartTime: _this.liveStartTime,
              liveTimeShiftUrl: _this.liveTimeShiftUrl,
              liveShiftSource: _this.liveShiftSource,
              recreatePlayer: _this.recreatePlayer,
              diagnosisButtonVisible: _this.diagnosisButtonVisible,
              disableSeek: _this.disableSeek,
              encryptType: _this.encryptType,
              progressMarkers: _this.progressMarkers,
              vodRetry: _this.vodRetry,
              liveRetry: _this.liveRetry,
            });

            // 绑定事件，当 AliPlayer 初始化完成后，将编辑器实例通过自定义的 ready 事件交出去
            _this.instance.on("ready", () => {
              this.$emit("ready", _this.instance);
            });

            _this.instance.on("play", () => {
              this.$emit("play", _this.instance);
            });

            _this.instance.on("pause", () => {
              this.$emit("pause", _this.instance);
            });

            _this.instance.on("ended", () => {
              this.$emit("ended", _this.instance);
            });

            _this.instance.on("liveStreamStop", () => {
              this.$emit("liveStreamStop", _this.instance);
            });

            _this.instance.on("m3u8Retry", () => {
              this.$emit("m3u8Retry", _this.instance);
            });

            _this.instance.on("hideBar", () => {
              this.$emit("hideBar", _this.instance);
            });

            _this.instance.on("waiting", () => {
              this.$emit("waiting", _this.instance);
            });

            _this.instance.on("snapshoted", () => {
              this.$emit("snapshoted", _this.instance);
            });

            _this.instance.on("timeupdate", () => {
              this.$emit("timeupdate", _this.instance);
            });

            _this.instance.on("requestFullScreen", () => {
              this.$emit("requestFullScreen", _this.instance);
            });

            _this.instance.on("cancelFullScreen", () => {
              this.$emit("cancelFullScreen", _this.instance);
            });

            _this.instance.on("error", () => {
              this.$emit("error", _this.instance);
            });

            _this.instance.on("startSeek", () => {
              this.$emit("startSeek", _this.instance);
            });

            _this.instance.on("completeSeek", () => {
              this.$emit("completeSeek", _this.instance);
            });
          });
        }
      },
      /**
       * 播放视频
       */
      play: function () {
        this.instance.play();
      },
      /**
       * 暂停视频
       */
      pause: function () {
        this.instance.pause();
      },
      /**
       * 重播视频
       */
      replay: function () {
        this.instance.replay();
      },
      /**
       * 跳转到某个时刻进行播放
       * @argument time 的单位为秒
       */
      seek: function (time) {
        this.instance.seek(time);
      },
      /**
       * 获取当前时间 单位秒
       */
      getCurrentTime: function () {
        return this.instance.getCurrentTime();
      },
      /**
       *获取视频总时长，返回的单位为秒
       * @returns 返回的单位为秒
       */
      getDuration: function () {
        return this.instance.getDuration();
      },
      /**
       获取当前的音量，返回值为0-1的实数ios和部分android会失效
       */
      getVolume: function () {
        return this.instance.getVolume();
      },
      /**
       设置音量，vol为0-1的实数，ios和部分android会失效
       */
      setVolume: function (vol) {
        this.instance.setVolume(vol);
      },
      /**
       *直接播放视频url，time为可选值（单位秒）目前只支持同种格式（mp4/flv/m3u8）之间切换暂不支持直播rtmp流切换
       *@argument url 视频地址
       *@argument time 跳转到多少秒
       */
      loadByUrl: function (url, time) {
        this.instance.loadByUrl(url, time);
      },
      /**
       * 设置播放速度
       *@argument speed 速度
       */
      setSpeed: function (speed) {
        this.instance.setSpeed(speed);
      },
      /**
       * 设置播放器大小w,h可分别为400px像素或60%百分比chrome浏览器下flash播放器分别不能小于397x297
       *@argument w 播放器宽度
       *@argument h 播放器高度
       */
      setPlayerSize: function (w, h) {
        this.instance.setPlayerSize(w, h);
      },
      /**
       *目前只支持H5播放器。
       暂不支持不同格式视频间的之间切换。
       暂不支持直播rtmp流切换。
       */
      replayByVidAndPlayAuth: function (vid, accId, accSecret, stsToken, authInfo, domainRegion) {
        this.instance.replayByVidAndPlayAuth(vid, accId, accSecret, stsToken, authInfo, domainRegion);
      },

      /***
       * 重新设置vid和权限，目前只支持H5播放器。
       暂不支持不同格式视频间的之间切换。
       暂不支持直播rtmp流切换。
       * @param vid 视频ID
       * @param playauth 播放权限
       */
      replayByVidAndAuthInfo: function (vid, playauth) {
        this.instance.replayByVidAndAuthInfo(vid, playauth);
      },

      /**
       * 目前只支持HTML5界面上的重载功能,暂不支持直播rtmp流切换m3u8）之间切换,暂不支持直播rtmp流切换
       *@argument vid 视频id
       *@argument playauth 播放凭证
       */
      reloaduserPlayInfoAndVidRequestMts: function (vid, playauth) {
        this.instance.reloaduserPlayInfoAndVidRequestMts(vid, playauth);
      },

      /***
       *设置截图参数
       * @param width 宽度
       * @param height 高度
       * @param rate 截图质量
       */
      setSanpshotProperties: function (width, height, rate) {
        this.instance.setSanpshotProperties(width, height, rate);
      },
      /**
       * 设置封面地址
       * @param cover 封面地址
       */
      setCover: function (cover) {
        this.instance.setCover(cover);
      },


      reloadPlayer: function () {
        this.isReload = true;
        this.initAliplayer();
        this.isReload = false;
      }
    }
  };
</script>

<style>
  @import url(//g.alicdn.com/de/prismplayer/2.8.2/skins/default/aliplayer-min.css);
</style>
